package org.parademo.equations.implementations;

import org.parademo.equations.base.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Random;

public class TestEquation_3DArray implements TestEquationInterface {

    public static final double e = 2.71828182845904523536;
    /**
     * To set the number of voters.
     */
    public int TOTAL_VOTERS = 100;
    public int TOTAL_ITERATIONS = 100;
    /**
     * Weighted votes for each voter, calculated and updated.
     */
    ArrayList<Double> weightedAverages = new ArrayList<Double>(TOTAL_VOTERS);
    /**
     * Individual randomly generated voting timings and tokens.
     */
    int[][] timings = new int[TOTAL_ITERATIONS][TOTAL_VOTERS];
    int[][] tokens = new int[TOTAL_ITERATIONS][TOTAL_VOTERS];
    /**
     * Used for generating the tokens and list of timings.
     */
    Random randomGenerator = new Random();
    /**
     * Weighted totals for and against the proposal.
     */
    double Wa = 0.0;
    double Wf = 0.0;
    /**
     * Number of votes.
     */
    int plusVotes = 0;
    int negativeVotes = 0;
    /**
     * Total of tokens.
     */
    int plusTotal = 125;
    int negativeTotal = -119;
    /**
     * Temporary variables.
     */
    int x = 0, y = 0;

    public TestEquation_3DArray() {

        for (int ci = 0; ci < TOTAL_ITERATIONS; ci++) {
            for (int cj = 0; cj < TOTAL_VOTERS; cj++) {
                timings[ci][cj] = randomGenerator.nextInt(30);
                tokens[ci][cj] = (randomGenerator.nextBoolean() ? 1 : -1) * randomGenerator.nextInt(6);
            }
        }

    }

    /**
     * Implementation of the function.
     */
    public double calculate(double index) {

        double result = (-1 * Math.pow(index, 2.0)) / (1900 - Math.pow(index, 2.0));
        return Math.pow(e, result);
    }

    public void updateWeightedAverage() {
    }

    public void updateWeightedAverage(Writer output) throws IOException {

        double temp = 0.0;

        for (int iteration = 0; iteration < TOTAL_ITERATIONS; iteration++) {

            this.plusVotes = 0;
            this.plusTotal = 0;

            this.negativeTotal = 0;
            this.negativeVotes = 0;

            this.Wa = 0.0;
            this.Wf = 0.0;

            for (int i = 0; i < TOTAL_VOTERS; i++) {

                x = this.tokens[iteration][i];
                y = this.timings[iteration][i];

                if (x > 0) {

                    plusVotes++;
                    plusTotal += x;

                    temp = x * calculate(y);
                    this.weightedAverages.add(temp);

                    Wf += temp;

                } else if (x < 0) {

                    negativeVotes++;
                    negativeTotal += x;

                    temp = x * calculate(y);
                    this.weightedAverages.add(temp);

                    Wa += temp;

                } else if (x == 0) {
                    this.weightedAverages.add(0.0);
                }

            }

            output.write("-------------------------------\n\n");
            output.write("The total votes for : " + this.plusVotes + "\n");
            output.write("The total votes against : " + this.negativeVotes + "\n");

            output.write("The total tokens for : " + this.plusTotal + "\n");
            output.write("The total tokens against : " + this.negativeTotal + "\n");

            output.write("The weighted total for : " + this.Wf + "\n");
            output.write("The weighted total against : " + this.Wa + "\n");

            output.write("-------------------------------\n\n");


        }
    }

    public static void main(String[] args) {

        Writer output;
        File file = new File("output_3DArray.txt");

        try {
            output = new BufferedWriter(new FileWriter(file));
            TestEquation_3DArray test = new TestEquation_3DArray();

            output.write("Output of TestEquation_3DArray \n");
            output.write("------------------------------\n\n");
            output.write("Test cycle of" + test.TOTAL_ITERATIONS + " iterations with" + test.TOTAL_VOTERS + " votes and tokens as follows: \n\n");

            test.updateWeightedAverage(output);

            output.close();

        } catch (IOException e) {

            e.printStackTrace();
        }

    }
}